import React, {CSSProperties} from "react";
import {List as AntdList, Form as AntdForm, Pagination as AntdPagination} from 'antd';
import {
    renderItems,
    VJsonComponent,
    VJsonComponentBase,
} from "../factory";
import _ from 'lodash'
import {autorun, toJS} from "mobx";
import {ComplexArrayResult, DataComponentProp, defaultMode, RefreshMode, VJsonDataComponentBase} from "../datasource";
import {GridState, GridVJsonDataProp, GridVJsonProp} from "./grid/grid_type";
import Grid from "./grid/grid";
import {NamePath} from "rc-field-form/lib/interface";
import {ApiObject} from "../ajax";
import {applyValue} from "..";
import * as mobx from "mobx";

export interface ListVJsonProp {
    bordered?: boolean
    footer?: string | React.ReactNode
    header?: string | React.ReactNode
    size?: 'default' | 'large' | 'small'
    itemLayout?: "horizontal" | "vertical"
    split?: boolean
    pagination?: boolean
    paginationOption?: {
        defaultPageSize?: number
        pageSizeOptions?: string[]
        showSizeChanger?: boolean
        showQuickJumper?: boolean
    }
    renderItem?: (item: any) => React.ReactNode
}

export interface ListVJsonDataProp extends ListVJsonProp, DataComponentProp<List> {
    formItemName: NamePath
}

export interface ListState {
    data: any
}

@VJsonComponent({
    view: 'list'
})
export default class List extends VJsonDataComponentBase<List, ListVJsonDataProp, ListState> {
    static defaultProps = {
        ...VJsonDataComponentBase.defaultProps,
        visible: true,
        pagination: true,
        paginationOption: {
            size: "small",
            defaultPageSize: 10,
            pageSizeOptions: ['10', '20', '50', '100'],
            showSizeChanger: true,
            showQuickJumper: true,
            showTotal: (total: number) => `总共 ${total} 条`
        },
    }

    private _loading: boolean = false
    private _data = mobx.observable.box([])
    private readonly dataSourceAfterSuper?: (sender: List, dataOrgin: any[], responseRaw: any, api: ApiObject, param?: RefreshMode) => ComplexArrayResult<any>

    @mobx.observable
    private mobxState: {
        needCount: boolean
        pageSize: number
        currentPage: number
        total: number
        columnHiddenSetting: any
    } = {
        needCount: true,
        pageSize: 10,
        currentPage: 1,
        total: 0,
        columnHiddenSetting: {},
    }

    constructor(props: any) {
        super(props);

        _.defaults(
            props.vjson,
            List.defaultProps
        )

        // 换掉了基类的 onDataSourceAfter 方法，替换为 dataSourceAfterSuper
        this.dataSourceAfterSuper = this.onDataSourceAfter
        this.onDataSourceAfter = this.dataSourceAfter

        // 设置默认 state
        this.mobxState.pageSize = props.vjson.paginationOption.defaultPageSize

        this.state = {
            ...this.state,
            data: []
        }
    }

    render() {
        if (!this.props.vjson.visible) {
            return null
        }

        const wrapperStyle: CSSProperties = {
            ...mobx.toJS(this.props.vjson.style)
        }
        if (this.props.vjson.height === 'flex') {
            wrapperStyle.flexGrow = 1
        } else {
            wrapperStyle.height = this.props.vjson.height
        }

        return (
            // @ts-ignore
            <div key={this.key} view_id={this.key} aria-roledescription={this.view}
                 style={wrapperStyle}
                 className={"yvan-grid-wrapper" + (this.props.vjson.fullscreen ? ' fullscreen' : '') + ' ' + (this.props.vjson.className)}>
                <AntdList bordered={this.props.vjson.bordered}
                          footer={this.props.vjson.footer}
                          header={this.props.vjson.header}
                          size={this.props.vjson.size}
                          itemLayout={this.props.vjson.itemLayout}
                          split={this.props.vjson.split}
                          dataSource={this.data}
                          renderItem={this.props.vjson.renderItem}
                          loading={this.props.vjson.loading}
                >
                </AntdList>
                {
                    this._renderPagination()
                }
            </div>
        )
    }

    set loading(value: boolean) {
        this._loading = value
    }

    get loading() {
        return this._loading
    }

    set data(value: any[]) {
        // @ts-ignore
        this._data.set(value)
    }

    get data() {
        return this._data.get()
    }

    private _renderPagination() {
        if (!this.props.vjson.pagination) {
            return null
        }

        return (
            <div className="yvan-grid-pagination">
                <AntdPagination
                    total={this.mobxState.total}
                    defaultPageSize={this.mobxState.pageSize}
                    // onShowSizeChange={this.onShowSizeChange.bind(this)}
                    current={this.mobxState.currentPage}
                    onChange={this._onPageChange.bind(this)}
                    {
                        ...this.props.vjson.paginationOption
                    }
                />
            </div>
        )
    }

    private _onPageChange(currentPage: number, pageSize?: number) {
        if (pageSize && pageSize !== this.mobxState.pageSize) {
            this.mobxState.pageSize = pageSize
            this.mobxState.currentPage = 1
            this.mobxState.needCount = true;
        } else {
            this.mobxState.currentPage = currentPage
            this.mobxState.needCount = false;
        }
        this.refresh({resetPage: false});
    }

    /**
     * 自定义 serverJS Data 参数
     */
    protected serverJsParamsParser(apiObject: ApiObject, param: RefreshMode = defaultMode()): Promise<ApiObject> {
        const me = this;
        return new Promise(resolve => {
            const pageOption: any = {}
            if (this.props.vjson.pagination) {
                const pageSize = this.mobxState.pageSize
                const currentPage = (this.mobxState.currentPage > 0 && param.resetPage === false) ? this.mobxState.currentPage - 1 : 0

                // 需要分页
                _.assign(pageOption, {
                    limit: pageSize,
                    limitOffset: currentPage * pageSize,
                    needCount: currentPage === 0 || me.mobxState.needCount
                })
            }
            me.mobxState.needCount = true;
            // @ts-ignore
            if (apiObject.method === 'server') {
                // 表格的标准请求为：
                //      filterModel: {}
                //      limit: 100
                //      limitOffset: 0
                //      needCount: true
                //      params: {…}
                //      sortModel: []

                const params = apiObject.data
                apiObject.data = {
                    params,
                }

                // console.log('业务代码写在这里', apiObject.data)
                _.assign(apiObject.data, pageOption)

            } else if (apiObject.method === 'invoke') {
                const params = apiObject.data
                apiObject.data = {
                    ...params,
                }
                // console.log('业务代码写在这里', apiObject.data)
                _.assign(apiObject.data, pageOption)
                apiObject.data = [apiObject.data]

            } else {
                // 自主性 ajax 只是添加一个 pagination 属性
                _.set(apiObject, 'pagination', pageOption)
            }

            if (param.isExportData === true) {
                _.set(apiObject, 'data.isExportData', true);
                _.set(apiObject, 'data.exportDataCount', me.props.vjson.exportDataCount)
            }
            resolve(apiObject)
        })
    }

    /**
     * 拿到原始的请求结果之后，需要进行下一步处理
     */
    private dataSourceAfter(sender: List, dataOrgin: any[], responseRaw: any, api: ApiObject, param: RefreshMode = defaultMode()): ComplexArrayResult<any> {
        const dataSourceAfterSuper = this.dataSourceAfterSuper || ((_, dataOrgin: any, responseRaw: any) => responseRaw)

        const me = this
        // 换掉了基类的 onDataSourceAfter 方法，要重新调用回来
        return new Promise(resolve => {
            applyValue(dataSourceAfterSuper.call(this, sender, dataOrgin, responseRaw, api, param)).then(res => {

                if (typeof res === 'undefined' || res === null) {
                    // 忽略或清空结果
                    return resolve(res)
                }

                if (param.isExportData) {
                    if (typeof res.pagination === 'object') {
                        // @ts-ignore
                        resolve(res.data)
                    } else {
                        // @ts-ignore
                        resolve(res)
                    }
                    return
                }
                if (this.props.vjson.pagination) {
                    if (typeof res.pagination === 'object') {
                        // 从 res 中能获取到 pagination
                        if (typeof res.pagination.total !== 'undefined') {
                            // 需要改变 total 数量
                            if (typeof res.pagination.current === 'undefined') {
                                // 只改变总数
                                mobx.transaction(() => {
                                    // @ts-ignore
                                    me.mobxState.total = ((!api) || (api && api.data && api.data.needCount === true) ? parseInt(res.pagination.total) : sender.mobxState.total)
                                })

                            } else {
                                // 改变总数、当前页号、页大小
                                mobx.transaction(() => {
                                    me.mobxState.currentPage = parseInt(res.pagination.current)
                                    // @ts-ignore
                                    me.mobxState.total = ((!api) || (api && api.data && api.data.needCount === true) ? parseInt(res.pagination.total) : sender.mobxState.total)
                                    me.mobxState.pageSize = parseInt(res.pagination.size)
                                })
                            }
                        }

                        // @ts-ignore
                        resolve(res.data)

                    } else {
                        // 处理分页数据
                        // mobx.transaction(() => {
                        //     me.mobxState.currentPage = parseInt(responseRaw.pagination.current)
                        //     me.mobxState.total = (parseInt(responseRaw.pagination.total) === 0 ? sender.mobxState.total : parseInt(responseRaw.pagination.total))
                        //     me.mobxState.pageSize = parseInt(responseRaw.pagination.size)
                        // })
                        mobx.transaction(() => {
                            me.mobxState.currentPage = 1
                            me.mobxState.total = 0
                        })

                        // @ts-ignore
                        resolve(res.data)
                    }
                } else {
                    resolve(res)
                }
            })
        })
    }

}
